package com.wutianyi.favority.bean;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.neo4j.graphdb.Direction;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.Transaction;

import com.wutianyi.favority.FavorityRepository;
import com.wutianyi.favority.constants.Constants;
import com.wutianyi.favority.rel.RelTypes;

/**
 * 对user node进行封装
 * 
 * @author hanjiewu
 * 
 */
public class User {
	private final Node underlyingNode;
	private final GraphDatabaseService graphDb;

	/**
     * 
     */
	private final FavorityRepository favorityRepository;

	/**
	 * 推荐用户的时候，说明有多少相同的链接
	 */
	private int sameLinkCount;

	public User(Node underlyingNode, FavorityRepository favorityRepository) {
		this.underlyingNode = underlyingNode;
		this.graphDb = underlyingNode.getGraphDatabase();
		this.favorityRepository = favorityRepository;
	}

	public Node getUnderlyingNode() {
		return underlyingNode;
	}

	public long getUserId() {
		return (Long) underlyingNode.getProperty(Constants.USER_ID_INDEX);
	}

	/**
	 * 1 成功 -1 系统异常
	 * 
	 * @param name
	 * @return
	 */
	public int addFolder(String name) {
		favorityRepository.createFolder(underlyingNode, name);
		return 1;
	}

	/**
	 * 0 无效操作 删除指定的文件夹，同时与该文件夹关联的链接将会同时删除
	 * 
	 * @param folderId
	 * @return
	 */
	public int removeFolder(long folderId) {
		Folder folder = getFolderById(folderId);
		if (null == folder) {
			return 0;
		}
		Transaction tx = graphDb.beginTx();
		try {
			Iterable<Relationship> rs = folder.getUnderlyingNode()
					.getRelationships(RelTypes.LINKED, Direction.OUTGOING);
			for (Relationship r : rs) {
				r.delete();
			}
			rs = underlyingNode.getRelationships(RelTypes.FOLDER,
					Direction.OUTGOING);
			for (Relationship r : rs) {
				if (r.getEndNode().equals(folder.getUnderlyingNode())) {
					r.delete();
					folder.getUnderlyingNode().delete();
					break;
				}
			}
			tx.success();
		} finally {
			tx.finish();
		}

		return 1;
	}

	/**
	 * 获取当前用户下的所有的文件夹
	 * 
	 * @return
	 */
	public List<Folder> getFolders() {
		List<Folder> folders = new ArrayList<Folder>();

		for (Relationship rs : underlyingNode.getRelationships()) {
			if (rs.getType().equals(RelTypes.FOLDER)) {
				folders.add(new Folder(rs.getOtherNode(underlyingNode)));
			}
		}

		return folders;
	}

	/**
	 * 根据文件夹的id获取文件夹的信息
	 * 
	 * @param folderId
	 * @return
	 */
	public Folder getFolderById(long folderId) {
		Iterable<Relationship> rs = underlyingNode.getRelationships(
				RelTypes.FOLDER, Direction.OUTGOING);
		for (Relationship r : rs) {
			if (r.getEndNode().getId() == folderId) {
				return new Folder(r.getEndNode());
			}
		}
		return null;
	}

	/**
	 * 根据文件夹的名称获取文件夹的信息 文件夹是可以具有相同名称的
	 * 
	 * @param value
	 * @return
	 */
	public List<Folder> getFolderByName(String value) {
		List<Folder> folders = new ArrayList<Folder>();
		Iterable<Relationship> rs = underlyingNode.getRelationships(
				RelTypes.FOLDER, Direction.OUTGOING);
		for (Relationship r : rs) {
			if (r.getEndNode().getProperty(Constants.FOLDER_NAME).equals(value)) {
				folders.add(new Folder(r.getEndNode()));
			}
		}
		return folders;
	}

	public List<Link> getLinks(long folderId) {
		Folder folder = getFolderById(folderId);
		if (null == folder) {
			return Collections.EMPTY_LIST;
		}
		return folder.getLinks();
	}

	/**
	 * 1 添加成功 -1 系统异常 0 非法的folderId 为指定的文件夹添加链接
	 * 
	 * @return
	 */
	public int addLink(long folderId, String link) {
		Folder folder = getFolderById(folderId);
		// 当前节点没有相应的文件夹id
		if (null == folder) {
			return 0;
		}
		Link l = favorityRepository.getLink(link);
		Transaction tx = favorityRepository.getGraphDb().beginTx();
		try {
			if (null == l) {
				l = favorityRepository.createLink(link);
			}
			favorityRepository.createRelationshipTo(folder.getUnderlyingNode(),
					l.getUnderlyingNode(), RelTypes.LINKED);
			l.increCount();
			tx.success();
			return 1;
		} finally {
			tx.finish();
		}

	}

	/**
	 * 0无效的folderId -1 无效的link
	 * 
	 * @param folderId
	 * @param link
	 * @return
	 */
	public int removeLink(long folderId, String link) {
		Folder folder = getFolderById(folderId);
		if (null == folder) {
			return 0;
		}
		Link l = favorityRepository.getLink(link);
		if (null == l) {
			return -1;
		}
		Transaction tx = favorityRepository.getGraphDb().beginTx();
		try {
			int r = favorityRepository.deleteRelationTo(
					folder.getUnderlyingNode(), l.getUnderlyingNode(),
					RelTypes.LINKED);
			l.desCount();
			return r;
		} finally {
			tx.success();
		}
	}

	@Override
	public int hashCode() {
		return underlyingNode.hashCode();
	}

	@Override
	public boolean equals(Object obj) {
		return obj instanceof User
				&& ((User) obj).getUnderlyingNode().equals(underlyingNode);
	}

	public int getSameLinkCount() {
		return sameLinkCount;
	}

	public void setSameLinkCount(int sameLinkCount) {
		this.sameLinkCount = sameLinkCount;
	}

}
